package me.youline.dataServer.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.perf4j.aop.Profiled;

public class IdPageSqlHelper {

	private List<Long> ids = new ArrayList<Long>();

	private String sqlCondition;
	
	private Long[] idsArray;
	
	private String sizeSQlFragment;
	
	private String sqlParamCondition;
	
	private static final String ID_FIRST_NAME = "idPageFirst";
	
	private static final String ID_SCEOND_NAME = "idPageSecond";
	
	private Map<String,Object> idsMap = new HashMap<String,Object>();

	private IdPageSqlHelper() {

	}
	
	@Profiled(tag = "utils-创建分页查询对象")
	public static IdPageSqlHelper create(IdPagination idPagination){
		return create(idPagination,"id");
	}
	
	
	@Profiled(tag = "utils-创建分页查询对象")
	public static IdPageSqlHelper create(IdPagination idPagination,
			String idName) {
		if(idPagination == null){
			return getNullIDPageSqlHelper(idPagination, idName);
		}
		IdPageSqlHelper e = new IdPageSqlHelper();
		if (idPagination.hasEndId() && idPagination.hasStartId()) {
			e.sqlCondition = String.format(" %s > ? and %s < ?", idName,
					idName);
			e.sqlParamCondition = String.format(" %s > :%s and %s < :%s ",idName,ID_FIRST_NAME,idName,ID_SCEOND_NAME);
			if (idPagination.isDescOrder()) {
				e.ids.add(idPagination.getEndId());
				e.ids.add(idPagination.getStartId());
				e.idsMap.put(ID_FIRST_NAME, idPagination.getEndId());
				e.idsMap.put(ID_SCEOND_NAME, idPagination.getStartId());
			} else {
				e.ids.add(idPagination.getStartId());
				e.ids.add(idPagination.getEndId());
				e.idsMap.put(ID_FIRST_NAME, idPagination.getStartId());
				e.idsMap.put(ID_SCEOND_NAME, idPagination.getEndId());
			}
		} else {
			if (idPagination.hasStartId()) {
				processExistStartId(e, idPagination, idName);
			} else if(idPagination.hasEndId()){
				processExistEndId(e, idPagination, idName);
			}else{
				e.sqlCondition = " 1=1 ";
			}
		}
		createPageSizeFragment(e, idPagination);
		e.buildObjArray();
		return e;
	}
	
	protected static IdPageSqlHelper getNullIDPageSqlHelper(IdPagination idPagination,
			String idName){
		IdPageSqlHelper e = new IdPageSqlHelper();
		e.idsArray =new Long[0];
		e.sizeSQlFragment = "";
		e.sqlCondition = " 1=1 ";
		return e;
	}
	
	
	protected static void createPageSizeFragment(IdPageSqlHelper e,IdPagination idPagination){
		if(idPagination.isUnLimitPageSize()){
			e.sizeSQlFragment = "";
		}else {
			e.sizeSQlFragment = " limit "+idPagination.getPageSize();
		}
	}

	private static void processExistStartId(IdPageSqlHelper e,
			IdPagination idPagination, String idName) {
		if (idPagination.isDescOrder()) {
			e.sqlCondition = String.format(" %s < ? ", idName);
			e.sqlParamCondition = String.format(" %s < :%s ",idName,ID_FIRST_NAME);
		} else {
			e.sqlCondition = String.format(" %s > ? ", idName);
			e.sqlParamCondition = String.format(" %s > :%s ",idName,ID_FIRST_NAME);
		}
		e.idsMap.put(ID_FIRST_NAME, idPagination.getStartId());
		e.ids.add(idPagination.getStartId());
	}
	
	protected  void buildObjArray(){
		this.idsArray = ids.toArray(new Long[ids.size()]);
	}

	private static void processExistEndId(IdPageSqlHelper e,
			IdPagination idPagination, String idName) {
		if (idPagination.isDescOrder()) {
			e.sqlCondition = String.format(" %s > ? ", idName);
			e.sqlParamCondition = String.format(" %s > :%s ",idName,ID_FIRST_NAME);
		} else {
			e.sqlCondition = String.format(" %s < ? ", idName);
			e.sqlParamCondition = String.format(" %s < :%s ",idName,ID_FIRST_NAME);
		}
		e.ids.add(idPagination.getEndId());
		e.idsMap.put(ID_FIRST_NAME, idPagination.getEndId());
	}

	public Long[] getIds() {
		return this.idsArray;
	}

	public String getPagingSqlCondition() {
		return sqlCondition;
	}
	
	
	public String getSizeSqlCondition(){
		return this.sizeSQlFragment;
	}

	public String getSqlParamCondition() {
		return sqlParamCondition == null ? " 1=1 " : sqlParamCondition;
	}

	public void setSqlParamCondition(String sqlParamCondition) {
		this.sqlParamCondition = sqlParamCondition;
	}

	public Map<String, Object> getIdsMap() {
		return idsMap;
	}

	public void setIdsMap(Map<String, Object> idsMap) {
		this.idsMap = idsMap;
	}
	
}
